package cn.hill4j.tool.spring.ext.mock;

import org.aopalliance.intercept.MethodInvocation;

import java.lang.reflect.Method;
import java.util.Objects;
/**
  * ClassName: MockHandler
  * Description: mock执行器
  * @author hillchen
  * Date: 2023/8/12
  * @version: 1.0
  */
class MockHandler {
    /**
     * mock的原始方法
     */
    private Method sourceMethod;
    /**
     * mock方法
     */
    private Method mockMethod;
    /**
     * mock处理bean
     */
    private Object mockBean;
    /**
     * mock校验bean
     */
    private MockChecker mockChecker;
    /**
     * 原始方法执行器
     */
    private MethodInvocation invocation;
    /**
     * 原始bean类型
     */
    private Class sourceClass;
    /**
     * @author hillchen
     * Description: 构造方法
     * Date: 2023/8/12 23:58
     * @param invocation 方法执行器
     **/
    public MockHandler(MethodInvocation invocation) {
        this.invocation = invocation;
    }

    /**
     * @author hillchen
     * Description: 获取mock的原始方法
     * Date: 2023/8/12 23:55
     * @return Method
     **/
    public Method getSourceMethod() {
        return sourceMethod;
    }
    /**
     * @author hillchen
     * Description: 设置mock的原始方法
     * Date: 2023/8/12 23:58
     * @param sourceMethod mock的原始方法
     **/
    public void setSourceMethod(Method sourceMethod) {
        this.sourceMethod = sourceMethod;
    }

    /**
     * @author hillchen
     * Description: 获取mock方法
     * Date: 2023/8/12 23:55
     * @return Method
     **/
    public Method getMockMethod() {
        return mockMethod;
    }

    /**
     * @author hillchen
     * Description: 设置mock方法
     * Date: 2023/8/12 23:58
     * @param mockMethod mock方法
     **/
    public void setMockMethod(Method mockMethod) {
        this.mockMethod = mockMethod;
    }

    /**
     * @author hillchen
     * Description: 获取mock处理bean
     * Date: 2023/8/12 23:55
     * @return Object
     **/
    public Object getMockBean() {
        return mockBean;
    }

    /**
     * @author hillchen
     * Description: 设置mock处理bean
     * Date: 2023/8/12 23:58
     * @param mockBean mock处理bean
     **/
    public void setMockBean(Object mockBean) {
        this.mockBean = mockBean;
    }

    /**
     * @author hillchen
     * Description: 获取mock校验bean
     * Date: 2023/8/12 23:55
     * @return MockChecker
     **/
    public MockChecker getMockChecker() {
        return mockChecker;
    }

    /**
     * @author hillchen
     * Description: 设置获取mock校验bean
     * Date: 2023/8/12 23:58
     * @param mockChecker 获取mock校验bean
     **/
    public void setMockChecker(MockChecker mockChecker) {
        this.mockChecker = mockChecker;
    }

    /**
     * @author hillchen
     * Description: 获取原始方法执行器
     * Date: 2023/8/12 23:55
     * @return MethodInvocation
     **/
    public MethodInvocation getInvocation() {
        return invocation;
    }

    /**
     * @author hillchen
     * Description: 设置原始方法执行器
     * Date: 2023/8/12 23:58
     * @param invocation 获取原始方法执行器
     **/
    public void setInvocation(MethodInvocation invocation) {
        this.invocation = invocation;
    }

    /**
     * @author hillchen
     * Description: 获取原始bean类型
     * Date: 2023/8/12 23:55
     * @return Class
     **/
    public Class getSourceClass() {
        return sourceClass;
    }

    /**
     * @author hillchen
     * Description: 设置原始bean类型
     * Date: 2023/8/12 23:58
     * @param sourceClass 原始bean类型
     **/
    public void setSourceClass(Class sourceClass) {
        this.sourceClass = sourceClass;
    }
    /**
     * @author hillchen
     * Description: 执行mock逻辑
     * Date: 2023/8/13 00:01
     * @param
     * @return void
     **/
    public Object invoke() throws Throwable {
        if (needMock()){
            return mockMethod.invoke(mockBean,invocation.getArguments());
        }
        return invocation.proceed();
    }

    private boolean needMock(){
        return Objects.nonNull(mockBean) && Objects.nonNull(mockMethod) &&
                (Objects.isNull(mockChecker) ||
                        mockChecker.needMock(this)
                        );
    }

}
